namespace Gamov.DeleteSdData.Main.Frame.Extensions
{
    using System;
    using System.Collections.Generic;

    public static partial class ObjectExtensions
    {
        public static string ToLogString(this object instance)
        {
            if (instance == null)
            {
                return string.Empty;
            }

            var properties = instance.GetType().GetProperties();
            var list = new List<string>();
            foreach (var prop in properties)
            {
                if (prop.PropertyType == typeof(string) || !prop.PropertyType.IsClass)
                {
                    list.Add($"{prop.Name}={prop.GetValue(instance)}");
                    continue;
                }
            }
            return $"[{string.Join(", ", list)}]";
        }
        public static string SafeToString(this object o)
        {
            if (o == null || o is DBNull)
            {
                return "";
            }
            else
            {
                return o.ToString();
            }
        }

        public static int SafeToInt(this object o)
        {
            if (o == null || o is DBNull)
            {
                return 0;
            }
            else
            {
                if (int.TryParse(o.SafeToString(), out var i))
                {
                    return i;
                }
                else
                {
                    return 0;
                }
            }
        }

        public static T SafeTo<T>(this object o)
        {
            T result = default;

            if (o == null || o is DBNull)
            {
                return result;
            }

            var oStr = o.SafeToString();
            var TypeT = typeof(T);
            if (TypeT == typeof(int) && int.TryParse(oStr, out var i))
            {
                result = (T)Convert.ChangeType(i, TypeT);
            }
            else if (TypeT == typeof(long) && long.TryParse(oStr, out var j))
            {
                result = (T)Convert.ChangeType(j, TypeT);
            }
            else if (TypeT == typeof(DateTime) && DateTime.TryParse(oStr, out var m))
            {
                result = (T)Convert.ChangeType(m, TypeT);
            }
            else if (TypeT == typeof(bool) && bool.TryParse(oStr, out var n))
            {
                result = (T)Convert.ChangeType(n, TypeT);
            }
            else if (TypeT == typeof(uint) && uint.TryParse(oStr, out var p))
            {
                result = (T)Convert.ChangeType(p, TypeT);
            }
            else if (TypeT == typeof(short) && short.TryParse(oStr, out var q))
            {
                result = (T)Convert.ChangeType(q, TypeT);
            }
            return result;
        }

        /// <summary>
        /// Get the value of the specified property name.
        /// </summary>
        /// <param name="instance">The instance that finds the property from.</param>
        /// <param name="propertyName">The property name.</param>
        /// <returns>An object representing the public property value of the specified name, if found; otherwise, <see cref="null"/>.</returns>
        public static object GetPropertyValue(this object instance, string propertyName)
        {
            if (instance == null)
            {
                throw new ArgumentNullException(nameof(instance));
            }
            if (string.IsNullOrEmpty(propertyName))
            {
                throw new ArgumentException($"{nameof(propertyName)} should be represented", nameof(propertyName));
            }

            var type = instance.GetType();
            var property = type.GetProperty(propertyName);
            if (property == null)
            {
                return null;
            }

            return property.GetValue(instance);
        }

    }
}
